import http from '@/http'
import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
import type { Ref } from 'vue'

// 定义返回类型的接口，包含 request 和 cancelRequest 方法
interface UseHttpReturn<T, P> {
  data: Ref<T | null>
  error: Ref<AxiosError | null>
  loading: Ref<boolean>
  request: (url: string, params?: P, options?: AxiosRequestConfig) => Promise<void>
  cancelRequest: () => void
}

const useHttp = <T = any, P = any>(): UseHttpReturn<T, P> => {
  const data = shallowRef<T | null>(null)
  const error = shallowRef<AxiosError | null>(null)
  const loading = ref(false)
  const controller = shallowRef<AbortController | null>(null)

  const request = async (url: string, params?: P, options: AxiosRequestConfig = {}) => {
    // 创建新的 AbortController 实例用于取消请求
    controller.value = new AbortController()
    const { signal } = controller.value
    loading.value = true
    error.value = null

    if (!options.method) {
      options.method = 'GET'
      options.params = params
    } else if (options.method.toLocaleUpperCase() === 'GET') {
      options.params = params
    } else {
      options.data = params
    }

    try {
      const response: AxiosResponse<T> = await http.request({
        url,
        ...options,
        signal // 传入 signal 以支持取消请求
      })
      data.value = response
    } catch (err) {
      error.value = err as AxiosError
    } finally {
      loading.value = false
    }
  }

  // 取消请求的函数
  const cancelRequest = () => {
    if (controller.value) {
      controller.value.abort()
    }
  }

  // 当组件卸载时取消请求
  onUnmounted(() => {
    cancelRequest()
  })

  return {
    data,
    error,
    loading,
    request,
    cancelRequest
  }
}

export default useHttp
